package com.xzixi.websocket.interceptablewebsocketdemo.config;

import com.xzixi.websocket.interceptablewebsocket.annotation.EnableInterceptableWebSocketMessageBroker;
import com.xzixi.websocket.interceptablewebsocket.config.InterceptableWebSocketMessageBrokerConfigurer;
import com.xzixi.websocket.interceptablewebsocket.extension.InterceptableWebMvcStompEndpointRegistry;
import com.xzixi.websocket.interceptablewebsocketdemo.websocket.AccessDecisionFromClientInterceptor;
import com.xzixi.websocket.interceptablewebsocketdemo.websocket.SessionIdRegistry;
import com.xzixi.websocket.interceptablewebsocketdemo.websocket.SessionIdRegistryInterceptor;
import com.xzixi.websocket.interceptablewebsocketdemo.websocket.SessionIdUnRegistryInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.messaging.StompSubProtocolErrorHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

/**
 * @author 薛凌康
 */
@Configuration
@EnableInterceptableWebSocketMessageBroker
public class InterceptableSecurityWebSocketConfig implements InterceptableWebSocketMessageBrokerConfigurer {

    /**
     * 异常处理器
     */
    @Bean
    public StompSubProtocolErrorHandler stompSubProtocolErrorHandler() {
        return new StompSubProtocolErrorHandler();
    }

    /**
     * 授权决策拦截器
     */
    @Bean
    public AccessDecisionFromClientInterceptor accessDecisionFromClientInterceptor() {
        return new AccessDecisionFromClientInterceptor();
    }

    /**
     * sessionId记录
     */
    @Bean
    public SessionIdRegistry sessionIdRegistry() {
        return new SessionIdRegistry();
    }

    /**
     * sessionId登记拦截器
     */
    @Bean
    public SessionIdRegistryInterceptor sessionIdRegistryInterceptor() {
        return new SessionIdRegistryInterceptor();
    }

    /**
     * sessionId移除拦截器
     */
    @Bean
    public SessionIdUnRegistryInterceptor sessionIdUnRegistryInterceptor() {
        return new SessionIdUnRegistryInterceptor();
    }

    @Override
    public void registerStompEndpoints(InterceptableWebMvcStompEndpointRegistry registry) {
        registry.addEndpoint("/endpoint")
                // 建立握手前将httpSession中的信息保存到webSocketSession，本案例将用户登录信息保存在httpSession
                .addInterceptors(new HttpSessionHandshakeInterceptor())
                .withSockJS();
        registry.setErrorHandler(stompSubProtocolErrorHandler());
        // 注册拦截器
        registry
                // 消息授权决策
                .addFromClientInterceptor(accessDecisionFromClientInterceptor())
                // sessionId记录
                .addFromClientInterceptor(sessionIdUnRegistryInterceptor())
                // sessionId移除
                .addToClientInterceptor(sessionIdRegistryInterceptor());
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic");
        registry.setApplicationDestinationPrefixes("/app");
    }

}
